package com.yonyou.ucf.mdd.isv.service;

import com.yonyou.bip.user.service.IGlobalizationPreferenceService;
import com.yonyou.diwork.multilingual.service.ILanguageService;
import com.yonyou.diwork.ott.RobotInvocationGetter;
import com.yonyou.diwork.service.auth.IDiWorkPermissionService;
import com.yonyou.diwork.service.auth.IServiceIsolateService;
import com.yonyou.diwork.service.pub.ITenantUserService;
import com.yonyou.diwork.service.session.extend.ISessionManagerExtendService;
import com.yonyou.iuap.auth.api.orgperm.IOrgPermManagerService;
import com.yonyou.iuap.data.service.itf.FuncOrgDataQryService;
import com.yonyou.iuap.log.rpc.IBusinessLogService;
import com.yonyou.iuap.ruleengine.service.relevant.RelevantRuleMgmtService;
import com.yonyou.ucf.mdd.api.interfaces.rpc.*;
import com.yonyou.ucf.mdd.ext.service.MddExtRuleApiService;
import com.yonyou.ucf.mdd.isv.rpc.impl.ISVBillQueryService;
import com.yonyou.ucf.mdd.isv.rpc.impl.ISVComOperateApiImpl;
import com.yonyou.ucf.mdf.iris.template.query.service.MdfTemplateQueryService;
import com.yonyou.ucf.transtype.service.itf.ITransTypeService;
import com.yonyou.workbench.service.session.ISessionManagerInnerService;
import com.yonyou.yonbip.iuap.xport.importing.progress.report.rest.ImportProgressReportApi;
import com.yonyoucloud.bill.service.ITranslateService;
import com.yonyoucloud.domain.service.IUserTenantService;
import com.yonyoucloud.enm.service.IEnmQueryService;
import com.yonyoucloud.iuap.ucf.mdd.error.UCFUnsupportedOperationException;
import com.yonyoucloud.iuap.ucf.mdd.starter.ucg.openapi.isv.router.module.DomainServiceFactory;
import com.yonyoucloud.iuap.ucf.mdd.starter.ucg.openapi.isv.router.module.refer.ReferApi;
import com.yonyoucloud.iuap.ucf.mdd.starter.ucg.openapi.isv.router.module.session.ISessionManagerInnerServiceApi;
import com.yonyoucloud.uretail.api.IBillQueryService;
import com.yonyoucloud.uretail.sys.pubItf.IDataPermissionService;
import com.yonyoucloud.uretail.sys.pubItf.IFuncPermissionService;
import com.yonyoucloud.uretail.sys.pubItf.IOrgPermissionService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;

/**
 * <p>Title</p>
 * <p>Description</p>
 *
 * @Author chouhl
 * @Date 2020-04-30$ 14:15$
 * @Version 1.0
 **/
@Slf4j
@Component
@RequiredArgsConstructor
public class ISVServiceReferenceFactory implements ISVServiceFactory {

    private final DomainServiceFactory domainServiceFactory;

    private final ApplicationContext context;

    @Override
    public <T> T getService(Class<T> clz, String group, String version, Integer timeout) {
        return this.getRestService(clz, group);
    }

    @Override
    public ISVComOperateApiImpl getIComOperateApiProxy(String group, String version, Integer timeout) {
        return new ISVComOperateApiImpl();
    }

    @Override
    public IComQueryApi getIComQueryApiProxy(String group, String version, Integer timeout) {
        return domainServiceFactory.buildCommonQueryApi(group);
    }

    @Override
    public ReferApi getIRefApiProxy(String group, String version, Integer timeout) {
        return domainServiceFactory.refApi(group);
    }

    /**
     * 升级3.0.7替换为MddExtRuleApiService
     *
     * @param group
     * @param version
     * @param timeout
     * @return
     */
    @Override
    public IRuleApi getIRuleApiProxy(String group, String version, Integer timeout) {
        return new MddExtRuleApiService();
    }

    @Override
    public IUimetaApi getIUimetaApiProxy(String group, String version, Integer timeout) {
        return domainServiceFactory.uiMetaApi(group);
    }

    @Override
    public IBillQueryService getBillQueryService(String group, String version, Integer timeout) {
        IComQueryApi comQueryApi = getIComQueryApiProxy(group, version, timeout);
        ISVComOperateApiImpl comOperateApi = getIComOperateApiProxy(group, version, timeout);
        return new ISVBillQueryService(comQueryApi, comOperateApi);
    }

    @Override
    public IBillQueryService getBillQueryService(String group) {
        return getBillQueryService(group, null, null);
    }

    @Override
    public <T> T getService(Class<T> clz, String group) {
        return getService(clz, group, null, null);
    }

    @Override
    public IComOperateApi getIComOperateApiProxy(String group) {
        return getIComOperateApiProxy(group, null, null);
    }

    @Override
    public IComQueryApi getIComQueryApiProxy(String group) {
        return getIComQueryApiProxy(group, null, null);
    }

    @Override
    public IRefApi getIRefApiProxy(String group) {
        return getIRefApiProxy(group, null, null);
    }

    @Override
    public IRuleApi getIRuleApiProxy(String group) {
        return getIRuleApiProxy(group, null, null);
    }

    @Override
    public IEnmQueryService getIEnumQueryService(String group) {
        return domainServiceFactory.enumQueryApi(group);
    }

    @Override
    public ISessionManagerInnerServiceApi getISessionManagerInnerService(String group) {
        return domainServiceFactory.sessionManagerInnerServiceApi(group);
    }

    @Override
    public IFuncPermissionService getIFuncPermissionService(String group) {
        return domainServiceFactory.funcPermissionServiceApi(group);
    }

    @Override
    public IDataPermissionService getIDataPermissionService(String domain) {
        return domainServiceFactory.dataPermissionServiceApi(domain);
    }

    @Override
    public IOrgPermissionService getIOrgPermissionService(String domain) {
        return domainServiceFactory.orgPermissionServiceApi(domain);
    }

    @Override
    public ITranslateService getITranslateService(String domain) {
        return domainServiceFactory.translateServiceApi(domain);
    }

    @Override
    public IDiWorkPermissionService getIDiWorkPermissionService(String group) {
        return domainServiceFactory.diWorkPermissionServiceApi(group);
    }

    @Override
    public IBusinessLogService getIBusinessLogService(String domain) {
        return domainServiceFactory.businessLogServiceApi(domain);
    }

    @Override
    public ILanguageService getILanguageService(String group) {
        return domainServiceFactory.languageServiceApi(group);
    }

    @Override
    public FuncOrgDataQryService getFuncOrgDataQryService(String group) {
        return domainServiceFactory.funcOrgDataQryServiceApi(group);
    }

    @Override
    public IOidAdapterApi getIOidAdapterApiProxy(String group) {
        return domainServiceFactory.oidAdapterApi(group);
    }
    @Override
    public RelevantRuleMgmtService getRelevantRuleMgmtApiProxy(String group) {
        return domainServiceFactory.relevantRuleMgmtServiceApi(group);
    }

    @Override
    public ISessionManagerExtendService getISessionManagerExtendService(String group) {
        return domainServiceFactory.sessionManagerExtendServiceApi(group);
    }

    @Override
    public MdfTemplateQueryService getMdfTemplateQueryService(String group) {
        return domainServiceFactory.mdfTemplateQueryServiceApi(group);
    }

    @Override
    public IOrgPermManagerService getOrgPermManagerService(String group) {
        return domainServiceFactory.OrgPermManagerServiceApi(group);
    }

    @Override
    public IServiceIsolateService getServiceIsolateService(String group) {
        return domainServiceFactory.ServiceIsolateServiceApi(group);
    }

    @Override
    public ImportProgressReportApi getImportProgressReportService(String group) {
        return domainServiceFactory.ImportProgressReportServiceImpl(group);
    }

    @Override
    public IGlobalizationPreferenceService getIGlobalizationPreferenceService(String group) {
        return domainServiceFactory.globalizationPreferenceServiceImpl(group);
    }

    @Override
    public IPoiSupportApi getIPoiSupportService(String group) {
        return domainServiceFactory.IPoiSupportApiImpl(group);
    }

    @Override
    public ITransTypeService getITransTypeService(String group) {
        return domainServiceFactory.transTypeService(group);
    }

        @Override
    public ITenantUserService getITenantUserService(String group) {
        return domainServiceFactory.TenantUserServiceImpl(group);
    }

    @Override
    public IUserTenantService getIUserTenantService(String group) {
        return domainServiceFactory.UserTenantServiceImpl(group);
    }

    @Override
    public RobotInvocationGetter getRobotInvocationGetter(String group) {
        return domainServiceFactory.robotInvocationGetter(group);
    }

    @SuppressWarnings("unchecked")
    protected <T> T getRestService(Class<T> clazz, String group) {
        if (IUimetaApi.class.isAssignableFrom(clazz)) {
            return (T) getIUimetaApiProxy(group, null, null);
        }
        if (IRuleApi.class.isAssignableFrom(clazz)) {
            return (T) getIRuleApiProxy(null);
        }
        if (IComOperateApi.class.isAssignableFrom(clazz)) {
            return (T) getIComOperateApiProxy(null);
        }
        if (IComQueryApi.class.isAssignableFrom(clazz)) {
            return (T) getIComQueryApiProxy(group);
        }
        if (IRefApi.class.isAssignableFrom(clazz)) {
            return (T) getIRefApiProxy(group);
        }
        if (IBillQueryService.class.isAssignableFrom(clazz)) {
            return (T) getBillQueryService(group);
        }
        if (IEnmQueryService.class.isAssignableFrom(clazz)) {
            return (T) getIEnumQueryService(group);
        }
        if (ISessionManagerInnerService.class.isAssignableFrom(clazz)) {
            return (T) getISessionManagerInnerService(group);
        }
        if (IFuncPermissionService.class.isAssignableFrom(clazz)) {
            return (T) getIFuncPermissionService(group);
        }
        if (IDataPermissionService.class.isAssignableFrom(clazz)) {
            return (T) getIDataPermissionService(group);
        }
        if (IOrgPermissionService.class.isAssignableFrom(clazz)) {
            return (T) getIOrgPermissionService(group);
        }
        if (ITranslateService.class.isAssignableFrom(clazz)) {
            return (T) getITranslateService(group);
        }
        if (IDiWorkPermissionService.class.isAssignableFrom(clazz)) {
            return (T) getIDiWorkPermissionService(group);
        }
        if (IBusinessLogService.class.isAssignableFrom(clazz)) {
            return (T) getIBusinessLogService(group);
        }
        if (ILanguageService.class.isAssignableFrom(clazz)) {
            return (T) getILanguageService(group);
        }
        if (FuncOrgDataQryService.class.isAssignableFrom(clazz)) {
            return (T) getFuncOrgDataQryService(group);
        }
        if (IOidAdapterApi.class.isAssignableFrom(clazz)) {
            return (T) getIOidAdapterApiProxy(group);
        }
        if (RelevantRuleMgmtService.class.isAssignableFrom(clazz)) {
            return (T) getRelevantRuleMgmtApiProxy(group);
        }
        if (ISessionManagerExtendService.class.isAssignableFrom(clazz)) {
            return (T) getISessionManagerExtendService(group);
        }
        if (ITransTypeService.class.isAssignableFrom(clazz)) {
            return (T) getITransTypeService(group);
        }
        if (MdfTemplateQueryService.class.isAssignableFrom(clazz)) {
            return (T) getMdfTemplateQueryService(group);
        }
        if (IOrgPermManagerService.class.isAssignableFrom(clazz)) {
            return (T) getOrgPermManagerService(group);
        }
        if (IServiceIsolateService.class.isAssignableFrom(clazz)) {
            return (T) getServiceIsolateService(group);
        }
        if (ImportProgressReportApi.class.isAssignableFrom(clazz)) {
            return (T) getImportProgressReportService(group);
        }
        if (IGlobalizationPreferenceService.class.isAssignableFrom(clazz)) {
            return (T) getIGlobalizationPreferenceService(group);
        }
        if (IPoiSupportApi.class.isAssignableFrom(clazz)) {
            return (T) getIPoiSupportService(group);
        }
        if (ITenantUserService.class.isAssignableFrom(clazz)) {
            return (T) getITenantUserService(group);
        }
        if (IUserTenantService.class.isAssignableFrom(clazz)) {
            return (T) getIUserTenantService(group);
        }
        if (RobotInvocationGetter.class.isAssignableFrom(clazz)) {
            return (T) getRobotInvocationGetter(group);
        }

        try {
            return context.getBean(clazz);
        } catch (Exception e) {
            log.warn("bean {} not found from application context", clazz.getSimpleName());
        }
        throw new UCFUnsupportedOperationException("unsupported bean of class " + clazz.getSimpleName());
    }
}
